﻿using System;
using System.ComponentModel;
using System.Reflection;

namespace Shp.Web.UI.WebControls.Iconized.Editors
{
   /// <summary>
   /// IconType enum Type Converter.
   /// </summary>
   public class IconTypeConverter : EnumConverter
   {
      #region Fields
      private Type _iconEnumType;
      #endregion Fields

      #region Properties
      #endregion Properties

      #region Methods
      /// <summary>
      /// Gets a value indicating whether this converter can convert an object to the given destination type using the context.
      /// </summary>
      /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
      /// <param name="destinationType">A <see cref="T:System.Type"/> that represents the type you wish to convert to.</param>
      /// <returns>
      /// true if this converter can perform the conversion; otherwise, false.
      /// </returns>
      public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
      {
         return (destinationType == typeof(string));
      }

      /// <summary>
      /// Converts the given value object to the specified destination type.
      /// </summary>
      /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
      /// <param name="culture">An optional <see cref="T:System.Globalization.CultureInfo"/>. If not supplied, the current culture is assumed.</param>
      /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
      /// <param name="destinationType">The <see cref="T:System.Type"/> to convert the value to.</param>
      /// <returns>
      /// An <see cref="T:System.Object"/> that represents the converted <paramref name="value"/>.
      /// </returns>
      /// <exception cref="T:System.ArgumentNullException">
      /// 	<paramref name="destinationType"/> is null.
      /// </exception>
      /// <exception cref="T:System.ArgumentException">
      /// 	<paramref name="value"/> is not a valid value for the enumeration.
      /// </exception>
      /// <exception cref="T:System.NotSupportedException">
      /// The conversion cannot be performed.
      /// </exception>
      public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
      {
         FieldInfo fi = this._iconEnumType.GetField(Enum.GetName(this._iconEnumType, value));
         DescriptionAttribute da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));

         return (da != null) ? da.Description : value.ToString();
      }

      /// <summary>
      /// Gets a value indicating whether this converter can convert an object in the given source type to an enumeration object using the specified context.
      /// </summary>
      /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
      /// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you wish to convert from.</param>
      /// <returns>
      /// true if this converter can perform the conversion; otherwise, false.
      /// </returns>
      public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
      {
         return (sourceType == typeof(string));
      }

      /// <summary>
      /// Converts the specified value object to an enumeration object.
      /// </summary>
      /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
      /// <param name="culture">An optional <see cref="T:System.Globalization.CultureInfo"/>. If not supplied, the current culture is assumed.</param>
      /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
      /// <returns>
      /// An <see cref="T:System.Object"/> that represents the converted <paramref name="value"/>.
      /// </returns>
      /// <exception cref="T:System.FormatException">
      /// 	<paramref name="value"/> is not a valid value for the target type.
      /// </exception>
      /// <exception cref="T:System.NotSupportedException">
      /// The conversion cannot be performed.
      /// </exception>
      public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
      {
         foreach (FieldInfo fi in this._iconEnumType.GetFields())
         {
            DescriptionAttribute da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));

            if ((da != null) && (da.Description == (string)value))
            {
               return Enum.Parse(this._iconEnumType, fi.Name);
            }
         }
         return Enum.Parse(this._iconEnumType, (string)value);
      }
      #endregion Methods

      #region Ctors
      /// <summary>
      /// Initializes a new instance of the <see cref="IconTypeConverter"/> class.
      /// </summary>
      /// <param name="type">A <see cref="T:System.Type"/> that represents the type of enumeration to associate with this enumeration converter.</param>
      public IconTypeConverter(Type type)
         : base(type)
      {
         this._iconEnumType = type;
      }
      #endregion Ctors

   }
}
